﻿using System.Collections.Generic;
using System.Threading.Tasks;
using SDCloudSolution.SDCloud.BusinessLayer.Model.Interfaces;
using SDCloudSolution.SDCloud.BusinessLayer.Utils;
using SDCloudSolution.SDCloud.DataLayer.Model.Interfaces;
using SDCloudSolution.SDCloud.Entities;
using SDCloudSolution.SDCloud.Entities.Models;

namespace SDCloudSolution.SDCloud.BusinessLayer.Model
{
    public class ModelComponent : IModelComponent
    {
        private readonly IModelDataProvider _modelDataProvider;

        public ModelComponent(IModelDataProvider modelDataProvider)
        {
            _modelDataProvider = modelDataProvider;
        }

        public Task<ModelEntity> GetModelByIdAsync(int modelId)
        {
            ComponentValidationHelper.EnsureValidId(modelId, "modelId");

            return _modelDataProvider.GetByIdAsync(modelId);
        }

        public Task<int> GetCountOfModelCopiesForUser(int originalModelId, int userId)
        {
            ComponentValidationHelper.EnsureValidId(originalModelId, nameof(originalModelId));
            ComponentValidationHelper.EnsureValidId(userId, nameof(userId));

            return _modelDataProvider.GetCountOfModelCopiesForUser(originalModelId, userId);
        }

        public Task<int> GetCountOfModelCopies(int originalModelId)
        {
            ComponentValidationHelper.EnsureValidId(originalModelId, nameof(originalModelId));

            return _modelDataProvider.GetCountOfModelCopies(originalModelId);
        }

        public Task<EntityCollection<ModelEntity>> FindModelsForUser(int userId, Paging paging)
        {
            ComponentValidationHelper.EnsureValidId(userId, "userId");
            ComponentValidationHelper.EnsureIsNotNull(paging, "paging");

            return _modelDataProvider.GetByUserIdAsync(userId, paging);
        }

        public Task<IEnumerable<ModelEntity>> FindAllModelsRelatedToPublicModel(int publicModelId)
        {
            ComponentValidationHelper.EnsureValidId(publicModelId, nameof(publicModelId));

            return _modelDataProvider.GetByPublicModelIdAsync(publicModelId);
        }

        public Task<IEnumerable<ModelEntity>> FindAllModelsForUser(int userId)
        {
            ComponentValidationHelper.EnsureValidId(userId, "userId");

            return _modelDataProvider.GetByUserIdAsync(userId);
        }

        public Task<EntityCollection<ModelEntity>> FindPublicModelsAsync(Paging paging)
        {
            return _modelDataProvider.GetPublicModelsAsync(paging);
        }

        public Task SaveModelAsync(ModelEntity entity)
        {
            ComponentValidationHelper.EnsureIsNotNull(entity, "entity");

            return entity.Id > 0 
                ? UpdateAsync(entity) 
                : InsertAsync(entity);
        }

        public Task DeleteAsync(ModelEntity entity)
        {
            ComponentValidationHelper.EnsureIsNotNull(entity, "entity");
            ComponentValidationHelper.EnsureValidId(entity.Id, "entity.Id");

            return _modelDataProvider.DeleteAsync(entity);
        }

        private Task UpdateAsync(ModelEntity entity)
        {
            ComponentValidationHelper.EnsureValidId(entity.Id, "entity.Id");
            return _modelDataProvider.UpdateAsync(entity);
        }

        private Task InsertAsync(ModelEntity entity)
        {
            return _modelDataProvider.InsertAsync(entity);
        }
    }
}
